<template>
  <div 
    ref="danmakuContainerRef" 
    class="danmaku-container"
    :class="{ 'is-hidden': !showDanmaku }"
  >
    <!-- 弹幕显示区域 -->
    <div class="danmaku-items">
      <div
        v-for="danmaku in activeDanmakus"
        :key="danmaku.id"
        class="danmaku-item"
        :class="{ 'my-danmaku': danmaku.isMyDanmaku }"
        :style="getDanmakuStyle(danmaku)"
      >
        {{ danmaku.content }}
      </div>
    </div>
  </div>
</template>

<style scoped>
.danmaku-container {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 1000;
}

.danmaku-container.is-hidden {
  display: none;
}

/* 弹幕基础样式 */
.danmaku-item {
  position: absolute;
  white-space: nowrap;
  font-family: "Microsoft YaHei", sans-serif;
  text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
  right: 0;
  transform: translateX(100%);
  animation: danmaku-move linear;
  z-index: 1001;
}

/* 弹幕移动动画 */
@keyframes danmaku-move {
  from {
    transform: translateX(8vw);
  }
  to {
    transform: translateX(-100vw);
  }
}

/* 添加自己发送的弹幕样式 */
.danmaku-item.my-danmaku {
  font-weight: bold;
  border: 1px solid currentColor;
  padding: 0 4px;
  border-radius: 4px;
}
</style>

<script setup>
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
import { danmakuApi } from '@/api/danmaku'
import wsClient from '@/utils/websocket' // 导入 WebSocket 客户端

// Props 定义
const props = defineProps({
  showDanmaku: {
    type: Boolean,
    default: true
  },
  videoHeight: {
    type: Number,
    required: true
  },
  videoWidth: {
    type: Number,
    required: true
  },
  currentTime: {
    type: Number,
    required: true
  },
  playing: {
    type: Boolean,
    default: false
  },
  videoId: {
    type: [Number, String],
    required: true
  }
})

// 轨道配置
const TRACK_HEIGHT = 30
const TRACK_PADDING = 4
const MIN_TRACKS = 8
const MAX_TRACKS = 20

// 状态管理
const danmakuContainerRef = ref(null)
const activeDanmakus = ref([])
const tracksPool = ref([])

// 弹幕类定义
class Danmaku {
  constructor(data) {
    this.id = data.id || danmakuIdCounter++
    this.videoId = data.videoId || 1
    this.userId = data.userId || 1
    this.content = data.content
    this.timePoint = data.timePoint || 0
    this.type = data.type || 1
    this.color = data.color || '#ffffff'
    this.fontSize = data.fontSize || 24
    this.createdAt = data.createdAt || new Date()
    this.status = data.status || 1
    this.trackId = null
    this.duration = 12
    this.isActive = false
    this.isMyDanmaku = data.isMyDanmaku || false
  }
}

// 初始化轨道
const initializeTracks = (height) => {
  const maxPossibleTracks = Math.floor(height / (TRACK_HEIGHT + TRACK_PADDING))
  const finalCount = Math.min(Math.max(maxPossibleTracks, MIN_TRACKS), MAX_TRACKS)
  
  tracksPool.value = Array(finalCount).fill(null).map((_, index) => ({
    id: index,
    isAvailable: true,
    lastUsedTime: 0
  }))
}

// 分配轨道
const allocateTrack = () => {
  const availableTrack = tracksPool.value.find(track => track.isAvailable)
  if (availableTrack) {
    availableTrack.isAvailable = false
    availableTrack.lastUsedTime = Date.now()
    return availableTrack.id
  }
  return null
}

// 释放轨道
const releaseTrack = (trackId) => {
  const track = tracksPool.value[trackId]
  if (track) {
    track.isAvailable = true
    track.lastUsedTime = Date.now()
  }
}

// 计算弹幕样式
const getDanmakuStyle = (danmaku) => {
  return {
    top: `${danmaku.trackId * (TRACK_HEIGHT + TRACK_PADDING)}px`,
    color: danmaku.color,
    fontSize: `${danmaku.fontSize}px`,
    animationDuration: `${danmaku.duration}s`,
    animationPlayState: props.playing ? 'running' : 'paused'
  }
}

// 添加弹幕时间点管理
const danmakuTimePoints = ref([])
const danmakuMap = ref(new Map())

// 添加弹幕方法
const addDanmaku = async (data) => {
  try {
    const danmakuData = {
      videoId: props.videoId,
      content: data.content,
      timePoint: Math.floor(props.currentTime * 1000),
      type: data.type === 'scroll' ? 1 : data.type === 'top' ? 2 : 3,
      color: data.color,
      fontSize: data.fontSize || 24
    }
    
    const res = await danmakuApi.addDanmaku(danmakuData)
    if (res.code === 1) {
      // 立即显示自己的弹幕
      const danmaku = new Danmaku({
        ...danmakuData,
        id: danmakuIdCounter++,
        isMyDanmaku: true
      })
      
      const trackId = allocateTrack()
      if (trackId !== null) {
        danmaku.trackId = trackId
        danmaku.isActive = true
        danmaku.duration = 12
        activeDanmakus.value.push({...danmaku})
        
        if (props.playing) {
          const releaseTimerId = setTimeout(() => {
            releaseTrack(trackId)
          }, danmaku.duration * 500)
          
          const removeTimerId = setTimeout(() => {
            removeDanmaku(danmaku.id)
          }, danmaku.duration * 1000)
          
          danmakuTimers.value.set(danmaku.id, {
            release: releaseTimerId,
            remove: removeTimerId
          })
        }
      }
    }
  } catch (error) {
    console.error('发送弹幕失败:', error)
  }
}

// 移除弹幕方法
const removeDanmaku = (danmakuId) => {
  if (!isComponentMounted.value) return
  
  activeDanmakus.value = activeDanmakus.value.filter(d => d.id !== danmakuId)
  
  const timers = danmakuTimers.value.get(danmakuId)
  if (timers) {
    clearTimeout(timers.release)
    clearTimeout(timers.remove)
    danmakuTimers.value.delete(danmakuId)
  }
}

let danmakuIdCounter = 1
const isComponentMounted = ref(true)
const danmakuTimers = ref(new Map())

// 监听播放状态
watch(() => props.playing, (isPlaying) => {
  if (isPlaying) {
    activeDanmakus.value.forEach(danmaku => {
      if (!danmakuTimers.value.has(danmaku.id)) {
        const releaseTimerId = setTimeout(() => {
          releaseTrack(danmaku.trackId)
        }, danmaku.duration * 500)
        
        const removeTimerId = setTimeout(() => {
          removeDanmaku(danmaku.id)
        }, danmaku.duration * 1000)
        
        danmakuTimers.value.set(danmaku.id, {
          release: releaseTimerId,
          remove: removeTimerId
        })
      }
    })
  } else {
    danmakuTimers.value.forEach((timers) => {
      clearTimeout(timers.release)
      clearTimeout(timers.remove)
    })
    danmakuTimers.value.clear()
  }
})

// 监听时间变化
watch(() => props.currentTime, (newTime) => {
  if (!props.playing) return
  
  const currentTimeMs = Math.floor(newTime * 1000)
  
  const matchingTimePoints = danmakuTimePoints.value.filter(timePoint => {
    return Math.abs(timePoint - currentTimeMs) <= 1000
  })
  
  if (matchingTimePoints.length > 0) {
    const danmakusToShow = []
    matchingTimePoints.forEach(timePoint => {
      const danmakus = danmakuMap.value.get(timePoint)
      if (danmakus) {
        const newDanmakus = danmakus.filter(d => !d.isActive && !activeDanmakus.value.some(ad => ad.id === d.id))
        danmakusToShow.push(...newDanmakus)
        
        danmakuTimePoints.value = danmakuTimePoints.value.filter(t => t !== timePoint)
        danmakuMap.value.delete(timePoint)
      }
    })
    
    const shuffledDanmakus = danmakusToShow.sort(() => Math.random() - 0.5)
    
    shuffledDanmakus.forEach(danmaku => {
      const trackId = allocateTrack()
      if (trackId !== null) {
        danmaku.trackId = trackId
        danmaku.isActive = true
        danmaku.duration = 12
        activeDanmakus.value.push({...danmaku})
        
        if (props.playing) {
          const releaseTimerId = setTimeout(() => {
            releaseTrack(trackId)
          }, danmaku.duration * 500)
          
          const removeTimerId = setTimeout(() => {
            removeDanmaku(danmaku.id)
          }, danmaku.duration * 1000)
          
          danmakuTimers.value.set(danmaku.id, {
            release: releaseTimerId,
            remove: removeTimerId
          })
        }
      }
    })
  }
}, { immediate: true })

// 监听视频ID变化
watch(() => props.videoId, async (newVideoId) => {
  if (!newVideoId) return
  
  activeDanmakus.value = []
  danmakuTimePoints.value = []
  danmakuMap.value.clear()
  
  try {
    const res = await danmakuApi.getDanmaku(newVideoId)
    if (res.code === 1 && res.data) {
      res.data.forEach(danmaku => {
        danmakuTimePoints.value.push(danmaku.timePoint)
        if (!danmakuMap.value.has(danmaku.timePoint)) {
          danmakuMap.value.set(danmaku.timePoint, [])
        }
        danmakuMap.value.get(danmaku.timePoint).push(danmaku)
      })
      
      danmakuTimePoints.value.sort((a, b) => a - b)
    }
  } catch (error) {
    console.error('加载弹幕失败:', error)
  }
}, { immediate: true })

// 修改弹幕消息处理函数
const handleDanmakuMessage = (message) => {
  console.log('收到弹幕消息:', message);
  
  // 如果消息本身就是弹幕对象
  const danmakuData = message.type === 'danmaku' ? message.data : message;
  
  // 检查是否是当前视频的弹幕
  if (parseInt(danmakuData.videoId) !== parseInt(props.videoId)) {
    console.log('不是当前视频的弹幕，跳过处理');
    return;
  }

  // 检查是否已经存在这条弹幕
  const existingDanmaku = activeDanmakus.value.find(d => 
    d.content === danmakuData.content && 
    d.userId === danmakuData.userId &&
    Math.abs(new Date(d.createdAt).getTime() - new Date().getTime()) < 5000
  );

  if (existingDanmaku) {
    console.log('弹幕已存在，跳过处理');
    return;
  }

  const danmaku = new Danmaku({
    ...danmakuData,
    isMyDanmaku: false
  });
  
  console.log('处理后的弹幕对象:', danmaku);
  
  // 如果弹幕时间点在当前播放时间附近，直接显示
  const currentTimeMs = Math.floor(props.currentTime * 1000);
  if (Math.abs(danmaku.timePoint - currentTimeMs) <= 1000) {
    const trackId = allocateTrack();
    if (trackId !== null) {
      danmaku.trackId = trackId;
      danmaku.isActive = true;
      danmaku.duration = 12;
      activeDanmakus.value.push({...danmaku});
      
      if (props.playing) {
        const releaseTimerId = setTimeout(() => {
          releaseTrack(trackId);
        }, danmaku.duration * 500);
        
        const removeTimerId = setTimeout(() => {
          removeDanmaku(danmaku.id);
        }, danmaku.duration * 1000);
        
        danmakuTimers.value.set(danmaku.id, {
          release: releaseTimerId,
          remove: removeTimerId
        });
      }
    }
  } else {
    // 如果不在当前时间点，添加到时间点集合
    danmakuTimePoints.value.push(danmaku.timePoint);
    if (!danmakuMap.value.has(danmaku.timePoint)) {
      danmakuMap.value.set(danmaku.timePoint, []);
    }
    danmakuMap.value.get(danmaku.timePoint).push(danmaku);
    danmakuTimePoints.value.sort((a, b) => a - b);
  }
}

// 修改生命周期钩子
onMounted(() => {
  isComponentMounted.value = true
  initializeTracks(props.videoHeight)
  
  // 添加弹幕消息处理器
  wsClient.addDanmakuHandler(handleDanmakuMessage)
})

onBeforeUnmount(() => {
  isComponentMounted.value = false
  
  // 移除弹幕消息处理器
  wsClient.removeDanmakuHandler(handleDanmakuMessage)
  
  // 清理其他资源
  danmakuTimers.value.forEach((timerId) => {
    clearTimeout(timerId)
  })
  danmakuTimers.value.clear()
  
  activeDanmakus.value = []
  danmakuTimePoints.value = []
  danmakuMap.value.clear()
})

// 暴露方法
defineExpose({
  addDanmaku,
  initializeTracks
})
</script>
